package com.example.itcacp.service;

import com.example.itcacp.util.UserSimilarityCalculator;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class RecommendationGenerator {

    private UserSimilarityCalculator similarityCalculator = new UserSimilarityCalculator();

    /**
     * 生成推荐列表
     * @param userItemMatrix 用户 - 内容矩阵
     * @param targetUserId 目标用户 ID
     * @param k 最相似的用户数量
     * @return 推荐的内容 ID 列表
     */
    public List<Long> generateRecommendations(Map<Long, Map<Long, Integer>> userItemMatrix, Long targetUserId, int k) {
        // 获取目标用户的内容操作记录
        Map<Long, Integer> targetUserItems = userItemMatrix.get(targetUserId);
        if (targetUserItems == null) {
            return new ArrayList<> ();
        }

        // 计算目标用户与其他用户的相似度
        Map<Long, Double> userSimilarities = new HashMap<> ();
        for (Map.Entry<Long, Map<Long, Integer>> entry : userItemMatrix.entrySet()) {
            Long userId = entry.getKey();
            if (userId != null && !userId.equals(targetUserId)) {
                Map<Long, Integer> otherUserItems = entry.getValue();
                double similarity = similarityCalculator.calculateCosineSimilarity(targetUserItems, otherUserItems);
                userSimilarities.put(userId, similarity);
            }
        }

        // 找到最相似的 K 个用户
        List<Map.Entry<Long, Double>> sortedSimilarities = new ArrayList<>(userSimilarities.entrySet());
        sortedSimilarities.sort((e1, e2) -> Double.compare(e2.getValue(), e1.getValue()));
        List<Long> topKUsers = new ArrayList<>();
        for (int i = 0; i < Math.min(k, sortedSimilarities.size()); i++) {
            topKUsers.add(sortedSimilarities.get(i).getKey());
        }

        // 推荐这些用户喜欢但目标用户未操作过的内容
        Set<Long> recommendedItems = new HashSet<> ();
        for (Long userId : topKUsers) {
            // 确保topKUsers中没有null
            if (userId != null) {
                Map<Long, Integer> otherUserItems = userItemMatrix.get ( userId );
                if (otherUserItems != null) {
                    for (Map.Entry<Long, Integer> entry : otherUserItems.entrySet ()) {
                        Long contentId = entry.getKey ();
                        if (!targetUserItems.containsKey ( contentId )) {
                            recommendedItems.add ( contentId );
                        }
                    }
                }
            }
        }
        return new ArrayList<>(recommendedItems);
    }
}
